﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using GraphDrawer.GraphProvider;

namespace GraphDrawer
{
    public partial class Menu : UserControl
    {
        String graphML = String.Empty;
        String model = String.Empty;
        public static EmptyPopUp PopUp;
        public static readonly GraphProviderServiceSoapClient graphProvider = new GraphProviderServiceSoapClient();
        UserControl m_helper;
        Source selectSource = new Source();
        DiseaseSelector diseaseSelector = new DiseaseSelector();
        public setupSimulation setupSelector;
        private GleeGraphDrawer layout;
        private VirtualEarthControl earth;
        private Dictionary<String, SolidColorBrush> statesColors = new Dictionary<string, SolidColorBrush>();
        public static Dictionary<GraphElement, GraphLayout.Interface.VisualItem> map = new Dictionary<GraphElement, GraphLayout.Interface.VisualItem>();
        SimulationReportChart chart = new SimulationReportChart();

		public TreeViewItem Report {
			get {
				return report;
			}
		}

        public UserControl Helper
        {
            get { return m_helper; }
            set
            {
                if (m_helper != null)
                    HelperHost.Children.Remove(m_helper);
                m_helper = value;
                if (m_helper != null)
                {
                    m_helper.SetValue(Grid.RowProperty, 1);
                    m_helper.SetValue(Grid.VerticalAlignmentProperty, VerticalAlignment.Bottom);
                    HelperHost.Children.Add(m_helper);
                    ShowLeftPanel();
                }
            }
        }

        public Menu()
        {
            InitializeComponent();
            this.SizeChanged += new SizeChangedEventHandler(Menu_SizeChanged);
            PopUp = new EmptyPopUp();
            PopUp.Visibility = Visibility.Collapsed;
            this.LayoutRoot.Children.Add(PopUp);
            selectSource.isSelectedSource += new RoutedEventHandler(selectSource_isSelectedSource);
            diseaseSelector.isSelectedDisease += new RoutedEventHandler(diseaseSelector_isSelectedDisease);
            Helper = selectSource;
            setupSelector = new setupSimulation(this);
        }

        void diseaseSelector_isSelectedDisease(object sender, RoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(diseaseSelector.GraphML))
            {
                System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(GraphDrawer.GraphML.graphml));
                System.IO.StringReader reader = new System.IO.StringReader(diseaseSelector.GraphML);
                var graph = (GraphDrawer.GraphML.graphml)ser.Deserialize(reader);

                foreach (var item in graph.graph.node)
                {
                    SolidColorBrush c = new SolidColorBrush(Colors.Transparent);
                    foreach (var color in item.data)
                    {
                        if (color.key == "nodeColor")
                        {

                            try
                            {
                                c = new SolidColorBrush(HexColor(color.Value));
                            }
                            catch (Exception)
                            {
                                try
                                {
                                    c = new SolidColorBrush((Color)(typeof(Colors)).GetProperty(color.Value).GetValue(null, null));
                                }
                                catch (Exception)
                                {


                                }
                            }

                        }
                    }
                    c.Opacity = 0.5;
                    statesColors.Add(item.id, c);
                }
            }
            setup.IsEnabled = true;
            Simulate.IsEnabled = true;
        }

        void selectSource_isSelectedSource(object sender, RoutedEventArgs e)
        {
            DiseaseNode.IsEnabled = true;
        }

        void Menu_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            PopUp.Width = e.NewSize.Width;
            PopUp.Height = e.NewSize.Height;
            if (layout != null)
            {
                layout.Width = e.NewSize.Width - this.LeftPanelSize.ActualWidth;
                layout.Height = e.NewSize.Height - 20;
            }

            if (earth != null)
            {
                earth.Map.Width = e.NewSize.Width - this.LeftPanelSize.ActualWidth;
                earth.Map.Height = e.NewSize.Height - 20;
            }

            chart.Width = e.NewSize.Width - this.LeftPanelSize.ActualWidth;
            chart.Height = e.NewSize.Height - 20;
        }

        private void NewPoll_Button_Click(object sender, RoutedEventArgs e)
        {
            string relativeURL = "PollDesigner/NewPoll.aspx";
            Uri currentURL = HtmlPage.Document.DocumentUri;
            //string[] pathParts = currentURL.LocalPath.Split('/');
            int idx = currentURL.OriginalString.IndexOf(currentURL.LocalPath);
            string newURL = currentURL.OriginalString.Substring(0, idx + 1) + relativeURL;
            HtmlPage.Window.Navigate(new Uri(newURL), "_blank");
        }

        private void Quest_Click(object sender, RoutedEventArgs e)
        {
            //TODO: Diplay popup "This future is not active yet. We are still working to bring it to you as soon as possible."
        }

        private void Network_Selected(object sender, RoutedEventArgs e)
        {
            Helper = selectSource;
        }

        private void Report_Selected(object sender, RoutedEventArgs e)
        {
            ContentHost.Children.Clear();            
            chart.Init();
            ContentHost.Children.Add(chart);
        }

        private void FullScreen_Click(object sender, RoutedEventArgs e)
        {
            //TODO: add changing style App.Current.Resources
            App.Current.Host.Content.IsFullScreen = !App.Current.Host.Content.IsFullScreen;
        }

        private void Disease_Selected(object sender, RoutedEventArgs e)
        {
            Helper = diseaseSelector;
        }

        private void Simulate_Selected(object sender, RoutedEventArgs e)
        {
            ContentHost.Children.Clear();
            HideLeftPanel();
            Point center = new Point(ContentHost.Width / 2, ContentHost.Height / 2);
            GetSetupSimulation();
            earth = null;

            layout = new GleeGraphDrawer(center, graphProvider, this);
            layout.Width =  this.Width - this.LeftPanelSize.ActualWidth;
            layout.Height = this.Height - 20;            
            ContentHost.Children.Add(layout);
        }

        private void GetSetupSimulation()
        {
            if (selectSource.sourceMethod == typeof(ImportNetwork))
            {
                setupSelector.SimulationSetup.diseaseModelGraphML = diseaseSelector.GraphML;
                setupSelector.SimulationSetup.networkGraphML = selectSource.import.graphML;
            }

            if (selectSource.sourceMethod == typeof(GenerateNetwork))
            {
                setupSelector.SimulationSetup.diseaseModelGraphML = diseaseSelector.GraphML;
                //TODO: check and fix
                setupSelector.SimulationSetup.networkGraph = selectSource.generator.graph;
            }
        }

        public String[] GetAvailableStates()
        {
            return statesColors.Keys.ToArray();
        }

        public SolidColorBrush GetColorForDisease(String Disease)
        {
            if (statesColors.ContainsKey(Disease))
                return statesColors[Disease];
            else
                return new SolidColorBrush(Colors.Transparent);
        }

        private Color HexColor(String hex)
        {
            //remove the # at the front
            hex = hex.Replace("#", "");

            byte a = 255;
            byte r = 255;
            byte g = 255;
            byte b = 255;

            int start = 0;

            //handle ARGB strings (8 characters long)
            if (hex.Length == 8)
            {
                a = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
                start = 2;
            }

            //convert RGB characters to bytes
            r = byte.Parse(hex.Substring(start, 2), System.Globalization.NumberStyles.HexNumber);
            g = byte.Parse(hex.Substring(start + 2, 2), System.Globalization.NumberStyles.HexNumber);
            b = byte.Parse(hex.Substring(start + 4, 2), System.Globalization.NumberStyles.HexNumber);

            return Color.FromArgb(a, r, g, b);
        }

        private void HideLeftPanel()
        {
            if (m_helper != null)
                m_helper.Visibility = Visibility.Collapsed;
        }

        private void ShowLeftPanel()
        {
            m_helper.Visibility = Visibility.Visible;
        }

        private void ImportNetwork_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectSource.Import_Click(sender, new RoutedEventArgs());
        }

        private void Generate_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectSource.Generate_Click(sender, new RoutedEventArgs());
        }

        private void OpenQuest_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectSource.Quest_Click(sender, new RoutedEventArgs());
        }

        private void setup_Selected(object sender, RoutedEventArgs e)
        {
            Helper = null;
            setupSelector.Init();
            ContentHost.Children.Clear();
            ContentHost.Children.Add(setupSelector);
        }

        private void VirtualEarth_Selected(object sender, RoutedEventArgs e)
        {
            HideLeftPanel();
            ContentHost.Children.Clear();
            GetSetupSimulation();
            layout = null;
            earth = new VirtualEarthControl(graphProvider, this);
            earth.Map.Width = ContentHost.ActualWidth + RigthPanelSize.ActualWidth;
            earth.Map.Height = ContentHost.ActualHeight;
            ContentHost.Children.Add(earth);
        }
    }
}
